package uuidutil

import (
	"fmt"
	"math"
	"strconv"
	"strings"
	"sync"
	"time"
)

type U62Util struct{}

/**
 * 取62位数值(时间戳+2位序号)
 * @param sPrefix 前缀
 */
func (u62 U62Util) Get(sPrefix ...string) string {
	str := fmt.Sprintf("%v%02d", time.Now().Unix(), u62.getNumber())
	//strInt64 := strconv.FormatInt(i64, 10) + fmt.Sprintf("%02d", u62.getNumber())
	id16, _ := strconv.Atoi(str)

	str = U62Util{}.DecimalToAny(id16, 62)

	if len(sPrefix) < 1 {
		return str
	}

	var build strings.Builder

	for _, val := range sPrefix {
		val = strings.TrimSpace(val)
		if "" == val {
			continue
		}

		build.WriteString(val)
	}

	build.WriteString(str)

	return build.String()
}

// 数字转62位
func (u62 U62Util) To(num int) string {
	return u62.DecimalToAny(num, 62)
}

// 取序号
func (u62 U62Util) getNumber() int {
	U62UtilLock.Lock() //加锁

	U62UtilNumber++
	if U62UtilNumber > 99 {
		U62UtilNumber = 1
	}

	U62UtilLock.Unlock() //解锁

	return U62UtilNumber
}

// 10进制转任意进制
func (u62 U62Util) DecimalToAny(num, n int) string {
	new_num_str := ""
	var remainder int
	var remainder_string string

	for num != 0 {
		remainder = num % n
		if 76 > remainder && remainder > 9 {
			remainder_string = U62UtilArray[remainder]
		} else {
			remainder_string = strconv.Itoa(remainder)
		}

		new_num_str = remainder_string + new_num_str
		num = num / n
	}

	return new_num_str
}

// map根据value找key
func (u62 U62Util) FindKey(in string) int {
	result := -1
	for k, v := range U62UtilArray {
		if in == v {
			result = k
			break
		}
	}

	return result
}

// 任意进制转10进制
func (u62 U62Util) AnyToDecimal(num string, n int) int {
	var new_num float64
	new_num = 0.0
	nNum := len(strings.Split(num, "")) - 1

	for _, value := range strings.Split(num, "") {
		tmp := float64(u62.FindKey(value))
		if tmp == -1 {
			break
		}

		new_num = new_num + tmp*math.Pow(float64(n), float64(nNum))
		nNum = nNum - 1
	}

	return int(new_num)
}

var (
	U62UtilLock   sync.Mutex     //保存锁
	U62UtilNumber            = 0 //序号

	U62UtilArray map[int]string = map[int]string{
		0:  "0",
		1:  "1",
		2:  "2",
		3:  "3",
		4:  "4",
		5:  "5",
		6:  "6",
		7:  "7",
		8:  "8",
		9:  "9",
		10: "a",
		11: "b",
		12: "c",
		13: "d",
		14: "e",
		15: "f",
		16: "g",
		17: "h",
		18: "i",
		19: "j",
		20: "k",
		21: "l",
		22: "m",
		23: "n",
		24: "o",
		25: "p",
		26: "q",
		27: "r",
		28: "s",
		29: "t",
		30: "u",
		31: "v",
		32: "w",
		33: "x",
		34: "y",
		35: "z",
		36: "A",
		37: "B",
		38: "C",
		39: "D",
		40: "E",
		41: "F",
		42: "G",
		43: "H",
		44: "I",
		45: "J",
		46: "K",
		47: "L",
		48: "M",
		49: "N",
		50: "O",
		51: "P",
		52: "Q",
		53: "R",
		54: "S",
		55: "T",
		56: "U",
		57: "V",
		58: "W",
		59: "X",
		60: "Y",
		61: "Z"}
)
